package com.eraasoftware.npa.client;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;

import com.eraasoftware.npa.server.MyServer;

public class ProcessManager {

	File directory;
	List<Process> processes = new ArrayList<Process>();
	boolean loggable = false;

	String host;
	int port;

	// RemoteService father;

	public ProcessManager(MyServer myServer) {
		this.host = "localhost";
		this.port = myServer.port();
	}

	public ProcessManager(RemoteService father) {
		this.host = father.host;
		this.port = father.port;
	}

	public Process spawn() throws IOException {
		return spawn(false);
	}

	public Process spawn(boolean master) throws IOException {

		String classpath = "-Djava.class.path=" + System.getProperty("java.class.path");
		String className = RemoteService.class.getName();
		String slave = master ? "n" : "y";
		ProcessBuilder processBuilder = new ProcessBuilder("java", classpath, className, "-s", slave, "-H", this.host,
				"-P", Integer.toString(this.port));

		processBuilder.redirectErrorStream(true);

		Process process = processBuilder.start();

		processes.add(process);
		if (loggable) {
			new LogHandler(process).start();
		}
		//
		// print();
		return process;

	}

	public void loggable(boolean loggable) {
		this.loggable = loggable;
	}

	public void directory(File directory) {
		this.directory = directory;
	}

	public File directory() {
		return directory;
	}

	public void killAll() {
		for (Process process : processes) {
			process.destroy();
		}
	}

	private class LogHandler extends Thread {
		Process process;

		public LogHandler(Process process) {
			this.process = process;
		}

		@Override
		public void run() {
			try {
				print();
			} catch (Exception e) {
				// TODO: handle exception
			}

		}

		public void print() throws IOException {
			ReadableByteChannel std = Channels.newChannel(process.getInputStream());
			WritableByteChannel stdout = Channels.newChannel(System.out);
			ByteBuffer bb = ByteBuffer.allocate(50);
			while (std.read(bb) > 0) {
				bb.flip();
				stdout.write(bb);

				bb.clear();
			}
		}

	}

}
